{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Labeling: Return Over Benchmark\n",
    "\n",
    "![image_example](img/MSFT_Return_vs_Benchmark.png)\n",
    "_*Fig. 1:*_ Returns of MSFT stock from March-April 2020 compared to returns on SPY. Green dots for when MSFT outperformed SPY, and red for when MSFT underperformed.\n",
    "\n",
    "\n",
    "## Abstract\n",
    "\n",
    "Labeling against benchmark is a simple method of labeling financial data in which time-indexed returns are labeled according to\n",
    "whether they exceed a set value. The benchmark can be either a constant value, or a pd.Series of values with an index matching\n",
    "that of the returns. The labels can be the numerical value of how much each observation's return exceeds the benchmark, or the sign of the excess.\n",
    "\n",
    "## Introduction\n",
    "The simplest method of labeling is just returning the sign of the return. However, sometimes it is desirable to quantify the return compared to a benchmark to better contextualize the returns. This is commonly done by using the mean or median of multiple stocks in the market. However, that data may not always be available, and sometimes the user might wish a specify a constant or more custom benchmark to compare returns against. \n",
    "\n",
    "The paper [\"Evaluating multiple classifiers for stock price direction prediction\"](https://www.sciencedirect.com/science/article/abs/pii/S0957417415003334) by Ballings et al., (2015) features this labeling method. In this paper, the authors label yearly forward stock returns against a predetermined benchmark, and use that labeled data to compare the performance of several machine learning algorithms in predicting long term price movements.\n",
    "\n",
    "## How it works\n",
    "\n",
    "At time $t$, given that price of a stock is $p_{t,n}$, benchmark is $B_t$, and return is:\n",
    "\n",
    "$$\n",
    "    r_{t, n} = \\frac{p_{t,n}}{p_{t-1,n}} - 1\n",
    "$$\n",
    "\n",
    "Note that $B_t$ is a scalar value corresponding to the benchmark at time $t$, while $B$ is the vector of all benchmarks across all timestamps. The labels are:\n",
    "\n",
    "$$\n",
    "    L(r_{t, n}) = r_{t, n} - B_t\n",
    "$$\n",
    "\n",
    "If categorical labels are desired:\n",
    "\n",
    "$$\n",
    "     \\begin{equation}\n",
    "     \\begin{split}\n",
    "       L(r_{t, n}) = \\begin{cases}\n",
    "       -1 &\\ \\text{if} \\ \\ r_{t, n} < B_t\\\\\n",
    "       0 &\\ \\text{if} \\ \\ r_{t, n} = B_t\\\\\n",
    "       1 &\\ \\text{if} \\ \\ r_{t, n} > B_t\\\\\n",
    "       \\end{cases}\n",
    "     \\end{split}\n",
    "     \\end{equation}\n",
    "$$\n",
    "\n",
    "If desired, the user can specify a [resampling period](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#dateoffset-objects) to apply to the price data prior to calculating returns. The user can also lag the returns to make them forward-looking. In the paper by Ballings et al., the authors use yearly forward returns, and compare them to benchmark values of 15%, 25%, and 35%.\n",
    "\n",
    "---\n",
    "## Examples of use"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import datetime as dt\n",
    "import matplotlib.pyplot as plt\n",
    "from pandas.plotting import register_matplotlib_converters\n",
    "register_matplotlib_converters()\n",
    "\n",
    "import yfinance as yf\n",
    "from mlfinlab.labeling import return_over_benchmark"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load price data.\n",
    "msft = yf.Ticker('MSFT')\n",
    "msft_df = msft.history(start='2020-3-1', end ='2020-5-1')\n",
    "spy = yf.Ticker('SPY')\n",
    "spy_df = spy.history(start='2020-3-1', end ='2020-5-1')\n",
    "\n",
    "# Closing prices.\n",
    "msft_price = msft_df['Close']\n",
    "spy_price = spy_df['Close']\n",
    "\n",
    "# SPY return for benchmark.\n",
    "spy_returns = spy_price.pct_change(periods=1)\n",
    "msft_returns = msft_price.pct_change(periods=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Single stock's returns against a benchmark"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can specify a constant benchmark, and return a positive label if the stock returns above 0.5% for the day. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1.0    24\n",
       " 1.0    18\n",
       "Name: Close, dtype: int64"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "return1 = return_over_benchmark(prices=msft_price, benchmark=0.005, binary=True, lag=False)\n",
    "return1.value_counts()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also use returns on SPY over the same time period as the benchmark. Note that the time indices between the returns and the benchmark must match."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       " 1.0    25\n",
       "-1.0    17\n",
       "Name: Close, dtype: int64"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "returns2 = return_over_benchmark(prices=msft_price, benchmark=spy_returns, binary=True, lag=False)\n",
    "returns2.value_counts()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can plot returns on MSFT over time, color coded by whether it exceeds return on SPY for the same day."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'Return of MSFT Compared to Return of SPY, March-April, 2020')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Set color for points, green for over benchmark, red for below.\n",
    "color = returns2.apply(lambda x: 'g' if x==1 else 'r')\n",
    "\n",
    "fig, ax = plt.subplots()\n",
    "ax.scatter(msft_price.index, msft_returns, color=color.to_list())\n",
    "ax.plot(msft_price.index, msft_returns)\n",
    "fig.autofmt_xdate()\n",
    "ax.set_xlim([dt.date(2020, 3, 1), dt.date(2020, 5, 1)])\n",
    "ax.set_xlabel('Date')\n",
    "ax.set_ylabel('Return')\n",
    "ax.set_title('Return of MSFT Compared to Return of SPY, March-April, 2020')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Yearly returns over benchmark"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the paper by Ballings et al., the authors use several machine learning techniques to predict one year ahead whether the return will exceed the threshold. They use thresholds of 15%, 25%, and 35%."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[*********************100%***********************]  16 of 16 completed\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ZM</th>\n",
       "      <th>FB</th>\n",
       "      <th>NVDA</th>\n",
       "      <th>MSFT</th>\n",
       "      <th>COST</th>\n",
       "      <th>BABA</th>\n",
       "      <th>CCL</th>\n",
       "      <th>SYY</th>\n",
       "      <th>AAPL</th>\n",
       "      <th>JPM</th>\n",
       "      <th>WFC</th>\n",
       "      <th>CVX</th>\n",
       "      <th>F</th>\n",
       "      <th>PFE</th>\n",
       "      <th>AMD</th>\n",
       "      <th>GE</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1980-12-31</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.077029</td>\n",
       "      <td>0.481528</td>\n",
       "      <td>0.364292</td>\n",
       "      <td>0.004038</td>\n",
       "      <td>0.381689</td>\n",
       "      <td>0.001963</td>\n",
       "      <td>0.000981</td>\n",
       "      <td>5.75000</td>\n",
       "      <td>0.005405</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1981-12-31</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.116834</td>\n",
       "      <td>0.312200</td>\n",
       "      <td>0.465781</td>\n",
       "      <td>0.003538</td>\n",
       "      <td>0.328943</td>\n",
       "      <td>0.001745</td>\n",
       "      <td>0.001013</td>\n",
       "      <td>2.93750</td>\n",
       "      <td>0.005331</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1982-12-31</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.231456</td>\n",
       "      <td>0.421558</td>\n",
       "      <td>0.519197</td>\n",
       "      <td>0.003981</td>\n",
       "      <td>0.245508</td>\n",
       "      <td>0.004049</td>\n",
       "      <td>0.001352</td>\n",
       "      <td>6.28125</td>\n",
       "      <td>0.009242</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1983-12-31</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.214502</td>\n",
       "      <td>0.343949</td>\n",
       "      <td>0.564066</td>\n",
       "      <td>0.005737</td>\n",
       "      <td>0.265647</td>\n",
       "      <td>0.006696</td>\n",
       "      <td>0.001445</td>\n",
       "      <td>16.81250</td>\n",
       "      <td>0.011817</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1984-12-31</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.197548</td>\n",
       "      <td>0.410975</td>\n",
       "      <td>0.719265</td>\n",
       "      <td>0.004195</td>\n",
       "      <td>0.318239</td>\n",
       "      <td>0.007563</td>\n",
       "      <td>0.001774</td>\n",
       "      <td>14.75000</td>\n",
       "      <td>0.011855</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            ZM  FB  NVDA  MSFT  COST  BABA  CCL       SYY      AAPL       JPM  \\\n",
       "Date                                                                            \n",
       "1980-12-31 NaN NaN   NaN   NaN   NaN   NaN  NaN  0.077029  0.481528  0.364292   \n",
       "1981-12-31 NaN NaN   NaN   NaN   NaN   NaN  NaN  0.116834  0.312200  0.465781   \n",
       "1982-12-31 NaN NaN   NaN   NaN   NaN   NaN  NaN  0.231456  0.421558  0.519197   \n",
       "1983-12-31 NaN NaN   NaN   NaN   NaN   NaN  NaN  0.214502  0.343949  0.564066   \n",
       "1984-12-31 NaN NaN   NaN   NaN   NaN   NaN  NaN  0.197548  0.410975  0.719265   \n",
       "\n",
       "                 WFC       CVX         F       PFE       AMD        GE  \n",
       "Date                                                                    \n",
       "1980-12-31  0.004038  0.381689  0.001963  0.000981   5.75000  0.005405  \n",
       "1981-12-31  0.003538  0.328943  0.001745  0.001013   2.93750  0.005331  \n",
       "1982-12-31  0.003981  0.245508  0.004049  0.001352   6.28125  0.009242  \n",
       "1983-12-31  0.005737  0.265647  0.006696  0.001445  16.81250  0.011817  \n",
       "1984-12-31  0.004195  0.318239  0.007563  0.001774  14.75000  0.011855  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tickers = \"AAPL MSFT COST PFE SYY F GE BABA AMD CCL ZM FB WFC JPM NVDA CVX\"\n",
    "\n",
    "data = yf.download(tickers, start=\"1980-01-01\", end=\"2020-05-01\", group_by=\"ticker\")\n",
    "data = data.loc[:, (slice(None), 'Adj Close')]\n",
    "data.columns = data.columns.droplevel(1)\n",
    "data.resample('Y').last().head()  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.5331991951710262, 0.4225352112676056, 0.32796780684104626)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get the labels as a flat array.\n",
    "returns15 = return_over_benchmark(prices=data, benchmark=0.15, binary=True, resample_by='Y', lag=True).values.flatten()\n",
    "returns25 = return_over_benchmark(prices=data, benchmark=0.25, binary=True, resample_by='Y', lag=True).values.flatten()\n",
    "returns35 = return_over_benchmark(prices=data, benchmark=0.35, binary=True, resample_by='Y', lag=True).values.flatten()\n",
    "\n",
    "# Get the count of positive returns, ignoring NaN.\n",
    "_, count15 = np.unique(returns15[~np.isnan(returns15)], return_counts=True)  # Given as [count of -1, count of 1].\n",
    "_, count25 = np.unique(returns25[~np.isnan(returns25)], return_counts=True)\n",
    "_, count35 = np.unique(returns35[~np.isnan(returns35)], return_counts=True)\n",
    "\n",
    "# Get the ratio of positive labels to all labels.\n",
    "ratio15 = count15[1]/count15.sum()\n",
    "ratio25 = count25[1]/count25.sum()\n",
    "ratio35 = count35[1]/count35.sum()\n",
    "ratio15, ratio25, ratio35"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can visualize the probability of positive returns based on the benchmarks used by Ballings et al. Obviously, higher benchmarks result in fewer positive labels. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'Probablility of positive labels based on benchmark')"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = plt.bar(['0.15', '0.25', '0.35'], [ratio15, ratio25, ratio35], width=0.3, color=['r', 'g', 'b'])\n",
    "plt.xlabel('Benchmark')\n",
    "plt.ylabel('Probability of positive label')\n",
    "plt.title('Probablility of positive labels based on benchmark')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Error Handling"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An exception will be raised if the index of benchmark (if benchmark is a pd.Series) does not match with the index of the returns. As previously noted, in order for the function to correctly subtract the benchmark from the returns, they must have the same time index. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "ename": "AssertionError",
     "evalue": "Index of returns and benchmark do not match. If resampling is used, index of benchmark must match index of resampled data./",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-9-5eb308063226>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m# Suppose we apply a resample period to price, but forget to do so for returns.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mreturn_over_benchmark\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmsft_price\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mspy_price\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresample_by\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'W'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhead\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32mc:\\users\\ruifan\\mlfinlab\\mlfinlab\\labeling\\return_vs_benchmark.py\u001b[0m in \u001b[0;36mreturn_over_benchmark\u001b[1;34m(prices, benchmark, binary, resample_by, lag)\u001b[0m\n\u001b[0;32m     40\u001b[0m     \u001b[1;31m# Check that index of benchmark matches index of prices, if benchmark is a pd.Series.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     41\u001b[0m     \u001b[1;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbenchmark\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpd\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mSeries\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 42\u001b[1;33m         \u001b[1;32massert\u001b[0m \u001b[0mprices\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mequals\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbenchmark\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m  \u001b[1;34m\"Index of returns and benchmark do not match. If resampling is \"\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     43\u001b[0m                                                       \u001b[1;34m\"used, index of benchmark must match index of resampled data./\"\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     44\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAssertionError\u001b[0m: Index of returns and benchmark do not match. If resampling is used, index of benchmark must match index of resampled data./"
     ]
    }
   ],
   "source": [
    "# Suppose we apply a resample period to price, but forget to do so for returns.\n",
    "return_over_benchmark(msft_price, spy_price, resample_by='W').head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## Conclusion"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook presents the method to label data according to return over a given benchmark. This method can return either numerical or categorical labels for observations. In this process, returns are first calculated from prices, with resampling if necessary. The returns are compared to a benchmark of returns. The benchmark is subtracted from the stock returns to determine the excess return over benchmark. The labels can be returned numerically or can be relabeled to represent their signs. This approach potentially gives the user more flexibility than labeling according to the mean or median at each time index. When making trading decisions, there may be an opportunity cost. Setting the benchmark equal to something like interest rate or market return would inform whether a trade is profitable compared to investing the assets elsewhere."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## References"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. Ballings, M., Van den Poel, D., Hespeels, N. and Gryp, R., 2015. Evaluating multiple classifiers for stock price direction prediction. Expert Systems with Applications, 42(20), pp.7046-7056.\n",
    "2. Coqueret, G. and Guida, T., 2020. Machine Learning For Factor Investing."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
